package com.whut.monitor.util;
import org.apache.hadoop.io.DataOutputBuffer;

import java.io.*;
import java.util.Map;
import java.util.TreeMap;

import static com.whut.monitor.util.ProtocolUtil.isWindows;

/**
 * Created by Administrator on 2017/10/12.
 */
public class CombineUtil {

    //文件跟路径
    private String rootPath = "C:\\Users\\Administrator\\Desktop\\";
    //上标
    private String fbgSHead = "SCH01-01,SCH01-02,SCH01-03,SCH01-04,SCH01-05,SCH01-06,SCH01-07,SCH01-08,SCH01-09,SCH01-10,SCH01-11,SCH01-12,SCH01-13,SCH01-14,SCH01-15,SCH02-01,SCH02-02,SCH02-03,SCH02-04,SCH02-05,SCH02-06,SCH02-07,SCH02-08,SCH02-09,SCH02-10,SCH02-11,SCH02-12,SCH02-13,SCH02-14,SCH02-15,SCH03-01,SCH03-02,SCH03-03,SCH03-04,SCH03-05,SCH03-06,SCH03-07,SCH03-08,SCH03-09,SCH03-10,SCH03-11,SCH03-12,SCH03-13,SCH03-14,SCH03-15,SCH04-01,SCH04-02,SCH04-03,SCH04-04,SCH04-05,SCH04-06,SCH04-07,SCH04-08,SCH04-09,SCH04-10,SCH04-11,SCH04-12,SCH04-13,SCH04-14,SCH04-15,SCH05-01,SCH05-02,SCH05-03,SCH05-04,SCH05-05,SCH05-06,SCH05-07,SCH05-08,SCH05-09,SCH05-10,SCH05-11,SCH05-12,SCH05-13,SCH05-14,SCH05-15,SCH06-01,SCH06-02,SCH06-03,SCH06-04,SCH06-05,SCH06-06,SCH06-07,SCH06-08,SCH06-09,SCH06-10,SCH06-11,SCH06-12,SCH06-13,SCH06-14,SCH06-15,";
    private String fbgTHead = "TCH01-01,TCH01-02,TCH01-03,TCH01-04,TCH01-05,TCH01-06,TCH01-07,TCH01-08,TCH01-09,TCH01-10,TCH01-11,TCH01-12,TCH01-13,TCH01-14,TCH01-15,TCH02-01,TCH02-02,TCH02-03,TCH02-04,TCH02-05,TCH02-06,TCH02-07,TCH02-08,TCH02-09,TCH02-10,TCH02-11,TCH02-12,TCH02-13,TCH02-14,TCH02-15,TCH03-01,TCH03-02,TCH03-03,TCH03-04,TCH03-05,TCH03-06,TCH03-07,TCH03-08,TCH03-09,TCH03-10,TCH03-11,TCH03-12,TCH03-13,TCH03-14,TCH03-15,TCH04-01,TCH04-02,TCH04-03,TCH04-04,TCH04-05,TCH04-06,TCH04-07,TCH04-08,TCH04-09,TCH04-10,TCH04-11,TCH04-12,TCH04-13,TCH04-14,TCH04-15,TCH05-01,TCH05-02,TCH05-03,TCH05-04,TCH05-05,TCH05-06,TCH05-07,TCH05-08,TCH05-09,TCH05-10,TCH05-11,TCH05-12,TCH05-13,TCH05-14,TCH05-15,TCH06-01,TCH06-02,TCH06-03,TCH06-04,TCH06-05,TCH06-06,TCH06-07,TCH06-08,TCH06-09,TCH06-10,TCH06-11,TCH06-12,TCH06-13,TCH06-14,TCH06-15,TCH07-01,TCH07-02,TCH07-03,TCH07-04,TCH08-01,TCH08-02,TCH08-03,TCH08-04,TCH09-01,TCH09-02,TCH09-03,TCH09-04,TCH10-01,TCH10-02,TCH10-03,TCH10-04,TCH10-05,TCH10-06,TCH10-07,TCH10-08,TCH10-09,TCH10-10,TCH11-01,TCH11-02,TCH11-03,TCH11-04,TCH11-05,TCH11-06,TCH11-07,TCH11-08,TCH11-09,TCH11-10,TCH12-01,TCH12-02,TCH12-03,TCH12-04,TCH12-05,TCH12-06,TCH12-07,TCH12-08,TCH12-09,TCH13-01,TCH13-02,TCH13-03,TCH13-04,TCH13-05,TCH13-06,TCH13-07,TCH13-08,TCH13-09,TCH13-10,TCH14-01,TCH14-02,TCH14-03,TCH14-04,TCH14-05,TCH14-06,TCH14-07,TCH14-08,TCH14-09,TCH14-10,TCH15-01,TCH15-02,TCH15-03,TCH15-04,TCH15-05,TCH15-06,TCH15-07,TCH15-08,TCH15-09,TCH15-10,TCH16-01,TCH16-02,TCH16-03,TCH16-04,TCH16-05,TCH16-06,TCH16-07,TCH16-08,TCH16-09,TCH16-10,TCH17-01,TCH17-02,TCH17-03,TCH17-04,TCH17-05,TCH17-06,TCH17-07,TCH17-08,TCH18-01,TCH18-02,TCH18-03,TCH18-04,TCH18-05,TCH18-06,TCH18-07,TCH18-08,TCH19-01,TCH19-02,TCH19-03,TCH19-04,TCH19-05,TCH19-06,TCH19-07,TCH19-08,TCH20-01,TCH20-02,TCH20-03,TCH20-04,TCH20-05,TCH20-06,TCH20-07,TCH20-08,TCH21-01,TCH21-02,TCH21-03,TCH21-04,TCH21-05,TCH21-06,TCH21-07,TCH21-08,TCH22-01,TCH22-02,TCH22-03,TCH22-04,TCH22-05,TCH22-06,TCH22-07,TCH22-08,";
    private String ds18Head = "DCH01-01,DCH01-02,DCH01-03,DCH01-04,DCH01-05,DCH01-06,DCH01-07,DCH01-08,DCH02-01, DCH02-02,DCH02-03,DCH02-04,DCH02-05,DCH02-06,DCH02-07,DCH02-08,DCH03-01,DCH03-02,DCH03-03,DCH03-04,DCH03-05,DCH03-06,DCH03-07,DCH03-08,DCH04-01,DCH04-02,DCH04-03,DCH04-04,DCH04-05,DCH04-06,DCH04-07,DCH04-08,DCH05-01,DCH05-02,DCH05-03,DCH05-04,DCH05-05,DCH05-06,DCH05-07,DCH05-08,DCH06-01,DCH06-02,DCH06-03,DCH06-04,DCH06-05,DCH06-06,DCH06-07,DCH06-08,DCH07-01,DCH07-02,DCH07-03,DCH07-04,DCH07-05,DCH07-06,DCH07-07,DCH07-08,DCH08-01,DCH08-02,DCH08-03,DCH08-04,DCH08-05,DCH08-06,DCH08-07,DCH08-08,";
    private String envHead = "ENV-Back,ENV-Right,ENV-Left,ENV-Front,";
    private String ccdHead = "CCD-X,CCD-Y,CCD-Z,";
    private String cncHead = "X轴坐标,Y轴坐标,Z轴坐标,主轴坐标,进给速度,主轴速度,X轴功率,Y轴功率,Z轴功率,主轴功率,X轴负荷,Y轴负荷,Z轴负荷,主轴负荷,暂停状态,";
    //Fbg基准波长
    private final double[][] fbgSStandareWave =
            {
                    {1535.812, 1537.794, 1539.784, 1541.831, 1543.769, 1545.771, 1547.778, 1549.832, 1551.942, 1553.969, 1555.9, 1557.744, 1559.768, 1561.9, 1563.821},
                    {1549.8, 1551.835, 1553.913, 1555.955, 1557.982, 1559.878, 1561.884, 1563.831},
                    {1535.855, 1537.92, 1539.875, 1541.905, 1543.903, 1545.854, 1547.871, 1549.908, 1551.819, 1553.809, 1555.166, 1557.806, 1559.772, 1561.839, 1563.772},
                    {1535.818, 1537.85, 1539.836, 1541.884, 1543.833, 1545.827, 1547.818, 1549.816, 1551.777, 1553.801, 1555.885, 1557.881, 1559.842, 1561.78, 1563.736},
                    {1535.781, 1537.786, 1539.775, 1541.843, 1543.813, 1545.788, 1547.763, 1549.777, 1551.792, 1553.774, 1555.843, 1557.841, 1559.891, 1561.979, 1563.997},
                    {1535.787, 1537.795, 1539.778, 1541.81, 1543.792, 1545.748, 1547.752, 1549.752, 1551.824, 1553.802, 1555.194, 1557.897, 1559.834, 1561.887, 1563.856},
                    {1535.818, 1537.837, 1539.827, 1541.867, 1543.772, 1545.768, 1547.764}
            };
    private final double[][] fbgTStandareWave =
            {
                    {1535.812, 1537.794, 1539.784, 1541.831, 1543.769, 1545.771, 1547.778, 1549.832, 1551.942, 1553.969, 1555.9, 1557.744, 1559.768, 1561.9, 1563.821},
                    {1549.8, 1551.835, 1553.913, 1555.955, 1557.982, 1559.878, 1561.884, 1563.831},
                    {1551.819, 1553.809, 1555.166, 1557.806, 1559.772, 1561.839, 1563.772},
                    {1535.818, 1537.85, 1539.836, 1541.884, 1543.833, 1545.827, 1547.818, 1549.816, 1551.777, 1553.801, 1555.885, 1557.881, 1559.842, 1561.78, 1563.736},
                    {1535.781, 1537.786, 1539.775, 1541.843, 1543.813, 1545.788, 1547.763, 1549.777, 1551.792, 1553.774, 1555.843, 1557.841, 1559.891, 1561.979, 1563.997},
                    {1535.787, 1537.795, 1539.778, 1541.81, 1543.792, 1545.748, 1547.752, 1549.752, 1551.824, 1553.802, 1555.194, 1557.897, 1559.834, 1561.887, 1563.856},
                    {1535.818, 1537.837, 1539.827, 1541.867, 1543.772, 1545.768, 1547.764},
                    {1535.855, 1537.92, 1539.875, 1541.905, 1543.903, 1545.854, 1547.871, 1549.908},
                    {1541.7464, 1557.825375, 1559.818, 1561.865},
                    {1552.851, 1554.886, 1556.906, 1558.834},
                    {1543.794, 1545.860, 1547.850, 1549.802},
                    {1536.79, 1539.759, 1542.691, 1545.759, 1548.719, 1551.835, 1554.707, 1557.714, 1560.756, 1563.697},
                    {1537.828, 1540.804, 1543.726, 1546.769, 1549.698, 1552.749, 1555.862, 1558.796, 1561.737, 1565.76},
                    {1533.177, 1536.68, 1539.622, 1542.445, 1545.646, 1548.485, 1551.763},
                    {1533.139, 1536.207, 1539.487, 1542.141, 1545.127, 1548.153, 1551.433, 1554.22, 1557.324, 1560.406},
                    {1532.322, 1535.331, 1538.348, 1541.278},
                    {1532.238, 1535.493, 1538.507, 1541.482, 1544.521, 1547.337, 1550.38, 1553.582, 1556.3, 1559.4},
                    {1533.363, 1536.476, 1538.212, 1541.983, 1544.813, 1548.062, 1550.77, 1554.162, 1556.829, 1559.949},
                    {1547.437, 1553.448, 1556.468, 1559.291},
                    {1537.852, 1540.774, 1543.699, 1546.773, 1549.698, 1552.776, 1555.862, 1558.742, 1561.839},
                    {1536.781, 1539.743, 1542.735, 1545.769, 1548.737, 1551.88, 1554.742, 1557.776, 1560.722, 1563.742},
                    {1537.861, 1540.801, 1543.742, 1546.799, 1549.847, 1552.743, 1555.881, 1558.777, 1561.789, 1565.814},
                    {1536.815, 1539.839, 1542.709, 1545.738, 1548.851, 1551.866, 1554.714, 1557.736, 1560.76, 1563.732},
                    {1537.796, 1540.815, 1543.709, 1546.75, 1549.719, 1552.755, 1555.831, 1558.739, 1561.774, 1565.756},
                    {1554.925, 1558.128, 1561.035}
            };

    /**
     * 输入字符串数组,用逗号连接，结尾有逗号
     *
     * @param cells
     * @return
     */
    private String linkString(String[] cells) {
        String str = "";
        for (int i = 0; i != cells.length; ++i) {
            str += cells[i] + ',';
        }
        return str;
    }
    /**
     * String[]转double[]
     *
     * @param strArray
     * @return
     */
    private double[] strArray2DoubleArray(String[] strArray) {
        double[] doubArray = new double[strArray.length];
        for (int i = 0; i != strArray.length; ++i) {
            doubArray[i] = Double.valueOf(strArray[i]);
        }
        return doubArray;
    }
    /**
     * 波长转应力函数
     *
     * @param tFirst FT第一行的波长
     * @param sFirst ST第一行的波长
     * @param tFact  FT某一行波长
     * @param sFact  ST某一行波长
     * @return
     */
    private String fbgWaveToStress(double tFirst, double sFirst, double tFact, double sFact) {
        String stress;
        if (Math.abs(tFirst) < 0.000001 || Math.abs(tFirst) < 0.000001) {
            stress = "0.00";
            return stress;
        }
        stress = String.format("%.3f", ((sFact - sFirst) / sFirst - (tFact - tFirst) / tFirst * 0.920863) / 0.776 * 1000000);
        return stress;
    }
    /**
     * 波长转应力函数
     *
     * @param tFirst FT第一行的波长
     * @param sFirst ST第一行的波长
     * @param tFact  FT某一行波长
     * @param sFact  ST某一行波长
     * @return
     */
    private String[] fbgWaveToStress(double[] tFirst, double[] sFirst, double[] tFact, double[] sFact) {
        String[] stress = new String[sFirst.length];
        for (int i = 0; i != sFirst.length && i != tFirst.length && i != sFact.length && i != tFact.length; ++i) {
            stress[i] = fbgWaveToStress(tFirst[i], sFirst[i], tFact[i], sFact[i]);
        }
        return stress;
    }
    /**
     * 解析输入的信息，例如types="001-DT,001-ET,001-FT,001-ST,001-CD,001-CN",
     * 返回值为{{001,DT},{001,ET}......}
     *
     * @param types 输入信息
     * @return
     */
    public String[][] parseInputInfo(String types) {
        String[] typeArray = types.split(",");
        String[][] devSenior = new String[typeArray.length][2];
        for (int i = 0; i != typeArray.length; ++i) {
            devSenior[i] = typeArray[i].split("-");
        }
        return devSenior;
    }

    public void setRootPath(String path)
    {
        rootPath=path;
    }
    /**
     * 横向扩展allMap，将map中与allMap key相同的value值拼接到allMap对应得value后
     *
     * @param allMap 要扩展的对象
     * @param map    扩展源
     * @return
     */
    public void appendMap(Map<String, String> allMap, Map<String, String> map) {
        if (allMap.size() == 0) {
            for (String aKey : map.keySet()) {
                allMap.put(aKey, map.get(aKey));
            }
            return;
        }
        for (String aKey : map.keySet()) {
            allMap.put(aKey, allMap.get(aKey) + map.get(aKey));
        }
    }
    /**
     * FT波长修复算法
     *
     * @param strWave 输入的波长字符串
     * @return 修复后的波长
     */
    public double[] fixFtWave(String strWave)
    {
        String[] waveArray=strWave.split(",");
        if(waveArray.length==219)//如果已经是修复过的，就不再修复
        {
            return strArray2DoubleArray(waveArray);
        }
        //将波长分散到通道和节点
        double[][] dWave=new double[25][20];
        double[] output=new double[219];
        int cnt=0;
        for(int i=0;i!=25;++i)
        {
            for(int j=0;j!=20;++j)
            {
                dWave[i][j]=Double.valueOf(waveArray[cnt++]);
            }
        }
        //修复波长
        cnt=0;
        for(int i=0;i!=fbgTStandareWave.length;++i)
        {
            for(int j=0;j!=fbgTStandareWave[i].length;++j)
            {
                for(int k=0;k!=20;++k)
                {
                    double d =dWave[i][k]-fbgTStandareWave[i][j];
                    if(d<1.75&&d>0)
                    {
                        output[cnt++]=dWave[i][k];
                        break;
                    }
                    if(k==19)//到最后都没找到符合要求的波长
                    {
                        output[cnt++]=0.00;
                    }
                }
            }
        }
        return output;
    }
    /**
     * ST波长修复算法
     *
     * @param strWave 输入的波长字符串
     * @return 修复后的波长
     */
    public double[] fixStWave(String strWave)
    {
        String[] waveArray=strWave.split(",");
        if(waveArray.length==90)//如果已经是修复过的，就不再修复
        {
            return strArray2DoubleArray(waveArray);
        }
        //将波长分散到通道和节点
        double[][] dWave=new double[7][20];
        double[] output=new double[90];
        int cnt=0;
        for(int i=0;i!=7;++i)
        {
            for(int j=0;j!=20;++j)
            {
                dWave[i][j]=Double.valueOf(waveArray[cnt++]);
            }
        }
        //修复波长
        cnt=0;
        for(int i=0;i!=fbgSStandareWave.length;++i)
        {
            for(int j=0;j!=fbgSStandareWave[i].length;++j)
            {
                for(int k=0;k!=20;++k)
                {
                    double d =dWave[i][k]-fbgSStandareWave[i][j];
                    if(d<1.75&&d>0)
                    {
                        output[cnt++]=dWave[i][k];
                        break;
                    }
                    if(k==19)//到最后都没找到符合要求的波长
                    {
                        output[cnt++]=0.00;
                    }
                }
            }
        }
        return output;
    }
    /**
     * 波长转温度，转后的温度直接写入ftMap
     * @param ftMap 波长Map
     * @return
     */
    public void fbgWaveToTemp(Map<String, String> ftMap) {
        for (String aKey : ftMap.keySet()) {
            double[] waveDoubleArray = fixFtWave(ftMap.get(aKey));
            String[] waveArray=new String[waveDoubleArray.length];
            int cnt=0;
            for (int i = 0; i != fbgTStandareWave.length; ++i)
            {
                for(int j=0;j != fbgTStandareWave[i].length;++j)
                {
                    waveArray[cnt] = String.format("%.3f", (waveDoubleArray[cnt] - fbgTStandareWave[i][j]) * 95.2381);
                    ++cnt;
                }
            }
            String strTemp = linkString(waveArray);
            ftMap.put(aKey, strTemp);
        }
    }

    /**
     * 波长转应力，转后的应力直接写入stMap
     * @param stMap FBG应力传感器波长Map
     * @param ftMap FBG温度传感器波长Map
     * @return
     */
    public void fbgWaveToStress(Map<String, String> stMap, Map<String, String> ftMap) {
        Map<Integer, String> stMapTemp = new TreeMap<>();
        Map<Integer, String> ftMapTemp = new TreeMap<>();
        Integer lineCnt = 0;
        for (String stKey : stMap.keySet()) {
            stMapTemp.put(lineCnt, stMap.get(stKey));
            ++lineCnt;
        }
        lineCnt = 0;
        for (String ftKey : ftMap.keySet()) {
            ftMapTemp.put(lineCnt, ftMap.get(ftKey));
            ++lineCnt;
        }
        double[] ftFirst = fixFtWave(ftMapTemp.get(0));
        double[] stFirst = fixStWave(stMapTemp.get(0));//得到ST和FT的第一行
        for (int i = 0; i != stMapTemp.size() && i != ftMapTemp.size(); ++i) {
            double[] stFact = fixStWave(stMapTemp.get(i));
            double[] ftFact = fixFtWave(ftMapTemp.get(i));
            String[] stressArray = fbgWaveToStress(ftFirst, stFirst, ftFact, stFact);
            String strStress = linkString(stressArray);
            stMapTemp.put(i, strStress);
        }
        lineCnt = 0;
        for (String aKey : stMap.keySet()) {
            if (lineCnt == stMapTemp.size()) {
                break;
            }
            stMap.put(aKey, stMapTemp.get(lineCnt));
            ++lineCnt;
        }
    }
    /**
     * 打印表
     * @param allMap 表内容
     * @param existSenior 存在的数据的传感器
     * @param date 日期
     * @return
     */
    public String printMap(Map<String, String> allMap, String existSenior,String date) {
        String[] devAndSenior = existSenior.split(",");
        if (devAndSenior.length <=1) {//只有设备号，没有存在的数据类型
            return "";
        }
        String fileName = date + "_"+devAndSenior[0] + "dev"; //日期、设备号
        String strHead = "Time,";
        for (int i = 1; i != devAndSenior.length; ++i) {
            fileName = fileName + devAndSenior[i] + "_"; //汇总的数据类型
            switch (devAndSenior[i]) {
                case "DT":
                    strHead += ds18Head;
                    break;
                case "ET":
                    strHead += envHead;
                    break;
                case "FT":
                    strHead += fbgTHead;
                    break;
                case "ST":
                    strHead += fbgSHead;
                    break;
                case "CN":
                    strHead += cncHead;
                    break;
                case "CD":
                    strHead += ccdHead;
                    break;
            }
        }
        fileName += "all.csv";//文件名
        strHead = strHead.substring(0, strHead.lastIndexOf(",")) + "\n";//上标
        if(!isWindows()) {
            rootPath = "/home/whut/soft/tomcat/webapps/ROOT/file/combine/";
        }
        File file = new File(rootPath+fileName);//创建文件
        try {
            BufferedWriter output = new BufferedWriter(new FileWriter(file)); //输出流
            output.write(strHead);//写入上标
            for (String aKey : allMap.keySet()) {//时间,数据\n格式写入
                output.write(aKey + "," + allMap.get(aKey).substring(0, allMap.get(aKey).lastIndexOf(",")) + "\n");
            }
            output.close();//关闭流
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "http://59.69.101.206/file/combine/"+fileName;//返回文件位置
    }
}

